﻿using System;
using System.Text;
using HslCommunication.BasicFramework;
using HslCommunication.Core;
using HslCommunication.Reflection;
using HslCommunication.Serial;

namespace HslCommunication.Profinet.Omron
{
	/// <summary>
	/// 欧姆龙的HostLink的C-Mode实现形式，地址支持携带站号信息，例如：s=2;D100<br />
	/// Omron's HostLink C-Mode implementation form, the address supports carrying station number information, for example: s=2;D100
	/// </summary>
	/// <remarks>
	/// 暂时只支持的字数据的读写操作，不支持位的读写操作。
	/// </remarks>
	// Token: 0x02000060 RID: 96
	public class OmronHostLinkCMode : SerialDeviceBase
	{
		/// <inheritdoc cref="M:HslCommunication.Profinet.Omron.OmronFinsNet.#ctor" />
		// Token: 0x060007ED RID: 2029 RVA: 0x0002A520 File Offset: 0x00028720
		public OmronHostLinkCMode()
		{
			base.ByteTransform = new ReverseWordTransform();
			base.WordLength = 1;
			base.ByteTransform.DataFormat = DataFormat.CDAB;
			base.ByteTransform.IsStringReverseByteWord = true;
		}

		/// <inheritdoc cref="P:HslCommunication.Profinet.Omron.OmronHostLinkOverTcp.UnitNumber" />
		// Token: 0x17000170 RID: 368
		// (get) Token: 0x060007EE RID: 2030 RVA: 0x0002A558 File Offset: 0x00028758
		// (set) Token: 0x060007EF RID: 2031 RVA: 0x0002A560 File Offset: 0x00028760
		public byte UnitNumber { get; set; }

		/// <inheritdoc cref="M:HslCommunication.Profinet.Omron.OmronFinsNet.Read(System.String,System.UInt16)" />
		// Token: 0x060007F0 RID: 2032 RVA: 0x0002A56C File Offset: 0x0002876C
		[HslMqttApi("ReadByteArray", "")]
		public override OperateResult<byte[]> Read(string address, ushort length)
		{
			byte unitNumber = (byte)HslHelper.ExtractParameter(ref address, "s", (int)this.UnitNumber);
			OperateResult<byte[]> operateResult = OmronHostLinkCMode.BuildReadCommand(address, length, false);
			bool flag = !operateResult.IsSuccess;
			OperateResult<byte[]> result;
			if (flag)
			{
				result = operateResult;
			}
			else
			{
				OperateResult<byte[]> operateResult2 = base.ReadBase(OmronHostLinkCMode.PackCommand(operateResult.Content, unitNumber));
				bool flag2 = !operateResult2.IsSuccess;
				if (flag2)
				{
					result = OperateResult.CreateFailedResult<byte[]>(operateResult2);
				}
				else
				{
					OperateResult<byte[]> operateResult3 = OmronHostLinkCMode.ResponseValidAnalysis(operateResult2.Content, true);
					bool flag3 = !operateResult3.IsSuccess;
					if (flag3)
					{
						result = OperateResult.CreateFailedResult<byte[]>(operateResult3);
					}
					else
					{
						result = OperateResult.CreateSuccessResult<byte[]>(operateResult3.Content);
					}
				}
			}
			return result;
		}

		/// <inheritdoc cref="M:HslCommunication.Profinet.Omron.OmronFinsNet.Write(System.String,System.Byte[])" />
		// Token: 0x060007F1 RID: 2033 RVA: 0x0002A610 File Offset: 0x00028810
		[HslMqttApi("WriteByteArray", "")]
		public override OperateResult Write(string address, byte[] value)
		{
			byte unitNumber = (byte)HslHelper.ExtractParameter(ref address, "s", (int)this.UnitNumber);
			OperateResult<byte[]> operateResult = OmronHostLinkCMode.BuildWriteWordCommand(address, value);
			bool flag = !operateResult.IsSuccess;
			OperateResult result;
			if (flag)
			{
				result = operateResult;
			}
			else
			{
				OperateResult<byte[]> operateResult2 = base.ReadBase(OmronHostLinkCMode.PackCommand(operateResult.Content, unitNumber));
				bool flag2 = !operateResult2.IsSuccess;
				if (flag2)
				{
					result = operateResult2;
				}
				else
				{
					OperateResult<byte[]> operateResult3 = OmronHostLinkCMode.ResponseValidAnalysis(operateResult2.Content, false);
					bool flag3 = !operateResult3.IsSuccess;
					if (flag3)
					{
						result = operateResult3;
					}
					else
					{
						result = OperateResult.CreateSuccessResult();
					}
				}
			}
			return result;
		}

		/// <summary>
		/// 读取PLC的当前的型号信息
		/// </summary>
		/// <returns>型号</returns>
		// Token: 0x060007F2 RID: 2034 RVA: 0x0002A6A4 File Offset: 0x000288A4
		[HslMqttApi]
		public OperateResult<string> ReadPlcModel()
		{
			OperateResult<byte[]> operateResult = base.ReadBase(OmronHostLinkCMode.PackCommand(Encoding.ASCII.GetBytes("MM"), this.UnitNumber));
			bool flag = !operateResult.IsSuccess;
			OperateResult<string> result;
			if (flag)
			{
				result = OperateResult.CreateFailedResult<string>(operateResult);
			}
			else
			{
				int num = Convert.ToInt32(Encoding.ASCII.GetString(operateResult.Content, 5, 2), 16);
				bool flag2 = num > 0;
				if (flag2)
				{
					result = new OperateResult<string>(num, "Unknown Error");
				}
				else
				{
					string @string = Encoding.ASCII.GetString(operateResult.Content, 7, 2);
					result = OmronHostLinkCMode.GetModelText(@string);
				}
			}
			return result;
		}

		/// <inheritdoc />
		// Token: 0x060007F3 RID: 2035 RVA: 0x0002A73C File Offset: 0x0002893C
		public override string ToString()
		{
			return string.Format("OmronHostLinkCMode[{0}:{1}]", base.PortName, base.BaudRate);
		}

		/// <summary>
		/// 解析欧姆龙的数据地址，参考来源是Omron手册第188页，比如D100， E1.100<br />
		/// Analyze Omron's data address, the reference source is page 188 of the Omron manual, such as D100, E1.100
		/// </summary>
		/// <param name="address">数据地址</param>
		/// <param name="isBit">是否是位地址</param>
		/// <param name="isRead">是否读取</param>
		/// <returns>解析后的结果地址对象</returns>
		// Token: 0x060007F4 RID: 2036 RVA: 0x0002A75C File Offset: 0x0002895C
		public static OperateResult<string, string> AnalysisAddress(string address, bool isBit, bool isRead)
		{
			OperateResult<string, string> operateResult = new OperateResult<string, string>();
			try
			{
				char c = address[0];
				char c2 = c;
				switch (c2)
				{
				case 'A':
					goto IL_BC;
				case 'B':
				case 'F':
				case 'G':
					goto IL_12A;
				case 'C':
					goto IL_87;
				case 'D':
					break;
				case 'E':
					goto IL_D5;
				case 'H':
					goto IL_A3;
				default:
					switch (c2)
					{
					case 'a':
						goto IL_BC;
					case 'b':
					case 'f':
					case 'g':
						goto IL_12A;
					case 'c':
						goto IL_87;
					case 'd':
						break;
					case 'e':
						goto IL_D5;
					case 'h':
						goto IL_A3;
					default:
						goto IL_12A;
					}
					break;
				}
				operateResult.Content1 = (isRead ? "RD" : "WD");
				goto IL_13A;
				IL_87:
				operateResult.Content1 = (isRead ? "RR" : "WR");
				goto IL_13A;
				IL_A3:
				operateResult.Content1 = (isRead ? "RH" : "WH");
				goto IL_13A;
				IL_BC:
				operateResult.Content1 = (isRead ? "RJ" : "WJ");
				goto IL_13A;
				IL_D5:
				string[] array = address.Split(new char[]
				{
					'.'
				}, StringSplitOptions.RemoveEmptyEntries);
				int num = Convert.ToInt32(array[0].Substring(1), 16);
				operateResult.Content1 = (isRead ? "RE" : "WE") + Encoding.ASCII.GetString(SoftBasic.BuildAsciiBytesFrom((byte)num));
				goto IL_13A;
				IL_12A:
				throw new Exception(StringResources.Language.NotSupportedDataType);
				IL_13A:
				bool flag = address[0] == 'E' || address[0] == 'e';
				if (flag)
				{
					string[] array2 = address.Split(new char[]
					{
						'.'
					}, StringSplitOptions.RemoveEmptyEntries);
					if (!isBit)
					{
						operateResult.Content2 = ushort.Parse(array2[1]).ToString("D4");
					}
				}
				else if (!isBit)
				{
					operateResult.Content2 = ushort.Parse(address.Substring(1)).ToString("D4");
				}
			}
			catch (Exception ex)
			{
				operateResult.Message = ex.Message;
				return operateResult;
			}
			operateResult.IsSuccess = true;
			return operateResult;
		}

		/// <summary>
		/// 根据读取的地址，长度，是否位读取创建Fins协议的核心报文<br />
		/// According to the read address, length, whether to read the core message that creates the Fins protocol
		/// </summary>
		/// <param name="address">地址，具体格式请参照示例说明</param>
		/// <param name="length">读取的数据长度</param>
		/// <param name="isBit">是否使用位读取</param>
		/// <returns>带有成功标识的Fins核心报文</returns>
		// Token: 0x060007F5 RID: 2037 RVA: 0x0002A97C File Offset: 0x00028B7C
		public static OperateResult<byte[]> BuildReadCommand(string address, ushort length, bool isBit)
		{
			OperateResult<string, string> operateResult = OmronHostLinkCMode.AnalysisAddress(address, isBit, true);
			bool flag = !operateResult.IsSuccess;
			OperateResult<byte[]> result;
			if (flag)
			{
				result = OperateResult.CreateFailedResult<byte[]>(operateResult);
			}
			else
			{
				StringBuilder stringBuilder = new StringBuilder();
				stringBuilder.Append(operateResult.Content1);
				stringBuilder.Append(operateResult.Content2);
				stringBuilder.Append(length.ToString("D4"));
				result = OperateResult.CreateSuccessResult<byte[]>(Encoding.ASCII.GetBytes(stringBuilder.ToString()));
			}
			return result;
		}

		/// <summary>
		/// 根据读取的地址，长度，是否位读取创建Fins协议的核心报文<br />
		/// According to the read address, length, whether to read the core message that creates the Fins protocol
		/// </summary>
		/// <param name="address">地址，具体格式请参照示例说明</param>
		/// <param name="value">等待写入的数据</param>
		/// <returns>带有成功标识的Fins核心报文</returns>
		// Token: 0x060007F6 RID: 2038 RVA: 0x0002A9F8 File Offset: 0x00028BF8
		public static OperateResult<byte[]> BuildWriteWordCommand(string address, byte[] value)
		{
			OperateResult<string, string> operateResult = OmronHostLinkCMode.AnalysisAddress(address, false, false);
			bool flag = !operateResult.IsSuccess;
			OperateResult<byte[]> result;
			if (flag)
			{
				result = OperateResult.CreateFailedResult<byte[]>(operateResult);
			}
			else
			{
				StringBuilder stringBuilder = new StringBuilder();
				stringBuilder.Append(operateResult.Content1);
				stringBuilder.Append(operateResult.Content2);
				for (int i = 0; i < value.Length / 2; i++)
				{
					stringBuilder.Append(BitConverter.ToUInt16(value, i * 2).ToString("X4"));
				}
				result = OperateResult.CreateSuccessResult<byte[]>(Encoding.ASCII.GetBytes(stringBuilder.ToString()));
			}
			return result;
		}

		/// <summary>
		/// 验证欧姆龙的Fins-TCP返回的数据是否正确的数据，如果正确的话，并返回所有的数据内容
		/// </summary>
		/// <param name="response">来自欧姆龙返回的数据内容</param>
		/// <param name="isRead">是否读取</param>
		/// <returns>带有是否成功的结果对象</returns>
		// Token: 0x060007F7 RID: 2039 RVA: 0x0002AA9C File Offset: 0x00028C9C
		public static OperateResult<byte[]> ResponseValidAnalysis(byte[] response, bool isRead)
		{
			bool flag = response.Length >= 11;
			OperateResult<byte[]> result;
			if (flag)
			{
				int num = Convert.ToInt32(Encoding.ASCII.GetString(response, 5, 2), 16);
				byte[] array = null;
				bool flag2 = response.Length > 11;
				if (flag2)
				{
					byte[] array2 = new byte[(response.Length - 11) / 2];
					for (int i = 0; i < array2.Length / 2; i++)
					{
						BitConverter.GetBytes(Convert.ToUInt16(Encoding.ASCII.GetString(response, 7 + 4 * i, 4), 16)).CopyTo(array2, i * 2);
					}
					array = array2;
				}
				bool flag3 = num > 0;
				if (flag3)
				{
					result = new OperateResult<byte[]>
					{
						ErrorCode = num,
						Content = array
					};
				}
				else
				{
					result = OperateResult.CreateSuccessResult<byte[]>(array);
				}
			}
			else
			{
				result = new OperateResult<byte[]>(StringResources.Language.OmronReceiveDataError);
			}
			return result;
		}

		/// <summary>
		/// 将普通的指令打包成完整的指令
		/// </summary>
		/// <param name="cmd">fins指令</param>
		/// <param name="unitNumber">站号信息</param>
		/// <returns>完整的质量</returns>
		// Token: 0x060007F8 RID: 2040 RVA: 0x0002AB7C File Offset: 0x00028D7C
		public static byte[] PackCommand(byte[] cmd, byte unitNumber)
		{
			byte[] array = new byte[7 + cmd.Length];
			array[0] = 64;
			array[1] = SoftBasic.BuildAsciiBytesFrom(unitNumber)[0];
			array[2] = SoftBasic.BuildAsciiBytesFrom(unitNumber)[1];
			array[array.Length - 2] = 42;
			array[array.Length - 1] = 13;
			cmd.CopyTo(array, 3);
			int num = (int)array[0];
			for (int i = 1; i < array.Length - 4; i++)
			{
				num ^= (int)array[i];
			}
			array[array.Length - 4] = SoftBasic.BuildAsciiBytesFrom((byte)num)[0];
			array[array.Length - 3] = SoftBasic.BuildAsciiBytesFrom((byte)num)[1];
			string @string = Encoding.ASCII.GetString(array);
			Console.WriteLine(@string);
			return array;
		}

		/// <summary>
		/// 获取model的字符串描述信息
		/// </summary>
		/// <param name="model">型号代码</param>
		/// <returns>是否解析成功</returns>
		// Token: 0x060007F9 RID: 2041 RVA: 0x0002AC28 File Offset: 0x00028E28
		public static OperateResult<string> GetModelText(string model)
		{
			uint num = <PrivateImplementationDetails>.ComputeStringHash(model);
			if (num <= 1827530846U)
			{
				if (num <= 501951850U)
				{
					if (num <= 468396612U)
					{
						if (num != 418210850U)
						{
							if (num == 468396612U)
							{
								if (model == "10")
								{
									return OperateResult.CreateSuccessResult<string>("C1000H");
								}
							}
						}
						else if (model == "09")
						{
							return OperateResult.CreateSuccessResult<string>("C250F");
						}
					}
					else if (num != 485174231U)
					{
						if (num == 501951850U)
						{
							if (model == "12")
							{
								return OperateResult.CreateSuccessResult<string>("C20H/C28H/C40H, C200H, C200HS, C200HX/HG/HE (-ZE)");
							}
						}
					}
					else if (model == "11")
					{
						return OperateResult.CreateSuccessResult<string>("C2000H/CQM1/CPM1");
					}
				}
				else if (num <= 535654183U)
				{
					if (num != 518876564U)
					{
						if (num == 535654183U)
						{
							if (model == "02")
							{
								return OperateResult.CreateSuccessResult<string>("C500");
							}
						}
					}
					else if (model == "03")
					{
						return OperateResult.CreateSuccessResult<string>("C120/C50");
					}
				}
				else if (num != 552431802U)
				{
					if (num == 1827530846U)
					{
						if (model == "0E")
						{
							return OperateResult.CreateSuccessResult<string>("C2000");
						}
					}
				}
				else if (model == "01")
				{
					return OperateResult.CreateSuccessResult<string>("C250");
				}
			}
			else if (num <= 2280673654U)
			{
				if (num <= 1894641322U)
				{
					if (num != 1877863703U)
					{
						if (num == 1894641322U)
						{
							if (model == "0A")
							{
								return OperateResult.CreateSuccessResult<string>("C500F");
							}
						}
					}
					else if (model == "0B")
					{
						return OperateResult.CreateSuccessResult<string>("C120F");
					}
				}
				else if (num != 2279835011U)
				{
					if (num == 2280673654U)
					{
						if (model == "30")
						{
							return OperateResult.CreateSuccessResult<string>("CS/CJ");
						}
					}
				}
				else if (model == "42")
				{
					return OperateResult.CreateSuccessResult<string>("CVM1-CPU21-E");
				}
			}
			else if (num <= 2313390249U)
			{
				if (num != 2296612630U)
				{
					if (num == 2313390249U)
					{
						if (model == "40")
						{
							return OperateResult.CreateSuccessResult<string>("CVM1-CPU01-E");
						}
					}
				}
				else if (model == "41")
				{
					return OperateResult.CreateSuccessResult<string>("CVM1-CPU11-E");
				}
			}
			else if (num != 2364708844U)
			{
				if (num != 2381486463U)
				{
					if (num == 2415041701U)
					{
						if (model == "22")
						{
							return OperateResult.CreateSuccessResult<string>("CV2000");
						}
					}
				}
				else if (model == "20")
				{
					return OperateResult.CreateSuccessResult<string>("CV500");
				}
			}
			else if (model == "21")
			{
				return OperateResult.CreateSuccessResult<string>("CV1000");
			}
			return new OperateResult<string>("Unknown model, model code:" + model);
		}
	}
}
